//this module will account for the awesomeness that is forwarding

/*
20:16= rt

EX/MEM.RegWrite= stage 2 C_Regwrite
Ex/MEM.RegisterRd = RwIn2
ID/EX. RegisterRs = Rs;
ID/EX. RegisterRt = Rt
IF/ID.RegisterRS = RaIn
IF/ID.RegisterRr = RbIn

*/

module Forward_Unit(MemRead, ForwardA, ForwardB, C_RegWrite3, C_RegWrite2, RwIn3, RwIn2, Rs, Rt, RaIn, RbIn);

// Ex/Mem Hazard
input C_RegWrite3, C_RegWrite2, MemRead;
input [4:0] Rs, Rt, RaIn, RbIn, RwIn2, RwIn3;

output [1:0] ForwardA, ForwardB;
reg [1:0] ForwardA, ForwardB;

always @( RwIn3 or RwIn2 or Rs or Rt or RaIn or RbIn)
begin

// MeM/WB hazard
if (C_RegWrite3 // Currently writing to a register
    && (RwIn3 != 0) //current is not register 0
    && (RwIn2!= Rs) //Next write register can't be register being read
    && (RwIn3 == Rs)) // Register being written is register being read
	ForwardA = 1;
else if(C_RegWrite2 && (RwIn2!= 0) && (RwIn2 == Rs))
    ForwardA = 2;
//this will deal with lw forwarding
else if(MemRead && (RaIn || RbIn) == RwIn2)
	ForwardA = 1;
else 
	ForwardA = 0;


if(C_RegWrite2 && (RwIn2!= 0) && (RwIn2 == Rt))
    ForwardB = 2;
else if(C_RegWrite3
    && (RwIn3  != 0) 
    && (RwIn2 != Rt) 
    && (RwIn3  == Rt))
	ForwardB = 1;
else if(MemRead && (RaIn || RbIn) == RwIn2)
	ForwardB = 1;
else 
	ForwardB = 0;
end
endmodule

